package entity

import (
	"encoding/json"
	"github.com/golang/protobuf/proto"
	"kop/pb"
	"kop/util/cd"
	"kop/util/date"
	"time"
)

type Conquer struct {
	RoleID        int32          `gorm:"type:int;primary_key"`
	PlayNum       int32          // 今日游玩次数
	Extra         int32          // 额外次数
	Date          int32          // 出征日期
	Type          pb.ConquerType `gorm:"type:smallint"` // 1征服 2复仇 3追击
	RoleIDs       []byte         `gorm:"type:jsonb"`    // 已随机到的对手ID
	CaptainData   []byte         // proto.Marshal(self.Captain)
	Role2Data     []byte         // proto.Marshal(self.Role2)
	Captains1Json []byte         `gorm:"type:jsonb"`     // json.Marshal(self.CaptainIDs1)
	Captains2Json []byte         `gorm:"type:jsonb"`     // json.Marshal(self.CaptainIDs2)
	CDTime        time.Time      `gorm:"column:CD_time"` // 刷新CD时间
	CreatedAt     time.Time
	UpdatedAt     time.Time

	Captain     *pb.ConquerCaptain `sql:"-"` // 我方当前上阵船长
	Role2       *pb.ConquerRole    `sql:"-"` // 对手数据
	CaptainIDs1 map[int32]bool     `sql:"-"`
	CaptainIDs2 map[int32]bool     `sql:"-"`
}

func (c *Conquer) AfterFind() error {

	if len(c.CaptainData) > 0 {
		c.Captain = &pb.ConquerCaptain{}
		_ = proto.Unmarshal(c.CaptainData, c.Captain)
	}

	if len(c.Role2Data) > 0 {
		c.Role2 = &pb.ConquerRole{}
		_ = proto.Unmarshal(c.Role2Data, c.Role2)
	}

	c.CaptainIDs1 = make(map[int32]bool)
	_ = json.Unmarshal(c.Captains1Json, &c.CaptainIDs1)

	c.CaptainIDs2 = make(map[int32]bool)
	_ = json.Unmarshal(c.Captains2Json, &c.CaptainIDs2)

	return nil
}

func (c *Conquer) BeforeSave() error {

	if c.Captain != nil {
		c.CaptainData, _ = proto.Marshal(c.Captain)
	} else {
		c.CaptainData = []byte{}
	}

	if c.Role2 != nil {
		c.Role2Data, _ = proto.Marshal(c.Role2)
	} else {
		c.Role2Data = []byte{}
	}

	c.Captains1Json, _ = json.Marshal(c.CaptainIDs1)
	c.Captains2Json, _ = json.Marshal(c.CaptainIDs2)

	return nil
}

func (c *Conquer) BeforeUpdate() error {

	if c.Captain != nil {
		c.CaptainData, _ = proto.Marshal(c.Captain)
	} else {
		c.CaptainData = []byte{}
	}

	if c.Role2 != nil {
		c.Role2Data, _ = proto.Marshal(c.Role2)
	} else {
		c.Role2Data = []byte{}
	}

	c.Captains1Json, _ = json.Marshal(c.CaptainIDs1)
	c.Captains2Json, _ = json.Marshal(c.CaptainIDs2)

	return nil
}

// 是否有对手
func (c *Conquer) HaveTarget() bool {
	return c.Role2 != nil
}

func (c *Conquer) Reset() {

	const PlayNum = 4

	c.Date = date.Date(time.Now())
	c.PlayNum = PlayNum
	c.Type = 0
	c.CDTime = cd.NewCD(time.Hour, 1).SetNum(1)
	c.RoleIDs = []byte("[]")
	c.Captain = nil
	c.Role2 = nil
	c.CaptainIDs1 = make(map[int32]bool)
	c.CaptainIDs2 = make(map[int32]bool)
}

//
//func (c *Conquer) FightingCaptains() []*pb.Captain {
//
//	var captains []*pb.Captain
//
//	for _, v := range c.Ships {
//		if v.State == pb.State_Doing {
//
//			for i := int32(1); i <= 5; i++ {
//				// 还有血量的准备打下一轮
//				if captain, _ := v.Captains[i]; captain != nil && captain.Attribute.COR > 0 {
//					captains = append(captains, captain)
//				}
//			}
//		}
//	}
//
//	return captains
//}

// 复仇|追击不改动其它的值
func (c *Conquer) RemoveTarget() {

	c.Role2 = nil
}

func (c *Conquer) CDStart() {

	var myCd = cd.NewCD(time.Hour, 1)

	c.Role2 = nil
	c.Date = date.Date(time.Now())
	c.Captain.Buffs = []int32{}
	c.CDTime = myCd.SetNum(0)
	c.Type = 0

}

// 第一位加个0占位表示有未选择的Buff
func (c *Conquer) NewBuff() {

	c.Captain.Buffs = append([]int32{0}, c.Captain.Buffs...)
}

func (c *Conquer) HaveNewBuff() bool {

	if c.Captain == nil {
		return false
	}

	return len(c.Captain.Buffs) > 0 && c.Captain.Buffs[0] == 0
}

func (c *Conquer) SetBuff(buffID int32) {

	c.Captain.Buffs[0] = buffID
}
